window.onload = () => {
    const VSHADER_SOURCE = `
    attribute vec4 a_Position;
    void main(){
      gl_Position = a_Position;
      gl_PointSize=4.0;
    }`;

    const FSHADER_SOURCE = `
    precision mediump float;
    uniform vec4 u_FragColor;
    void main(){
      gl_FragColor = u_FragColor;
    }`;
    const canvas = document.getElementById('webgl');
    const gl = getWebGLContext(canvas);
    if (!gl) {
        console.log('Fail');
        return;
    }
    if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
        console.log('Failed');
        return;
    }

    let a_Position = gl.getAttribLocation(gl.program, 'a_Position');
    let u_FragColor = gl.getUniformLocation(gl.program, 'u_FragColor');

    const translationPosition = (x1, y1, x2, y2, lineWidthHalf) => {
        let vectorXab = x2 - x1;
        let vectorYab = y2 - y1;
        let temp = lineWidthHalf * vectorXab / Math.sqrt(vectorYab * vectorYab + vectorXab * vectorXab);

        let ya1 = y1 + temp;
        let xa1 = vectorXab === 0 ? x1 - lineWidthHalf : x1 - vectorYab * (ya1 - y1) / vectorXab;
        let ya2 = y1 - temp;
        let xa2 = vectorXab === 0 ? x1 + lineWidthHalf : x1 - vectorYab * (ya2 - y1) / vectorXab;

        let xb1 = xa1 + vectorXab;
        let xb2 = xa2 + vectorXab;
        let yb1 = ya1 + vectorYab;
        let yb2 = ya2 + vectorYab;
        return [xa1, ya1, xa2, ya2, xb1, yb1, xb2, yb2];
    };

    const pointInPolgon = (p, p1, p2, p3, p4) => {
        let p1p2 = [p2[0] - p1[0], p2[1] - p1[1]];
        let p1p = [p[0] - p1[0], p[1] - p1[1]];
        let temp1 = p1p2[0] * p1p[0] + p1p[1] * p1p2[1];
        let p3p4 = [p4[0] - p3[0], p4[1] - p3[1]];
        let p3p = [p[0] - p3[0], p[1] - p3[1]];
        let temp2 = p3p[0] * p3p4[0] + p3p4[1] * p3p[1];
        if (temp1 * temp2 >= 0) {
            let p2p3 = [p3[0] - p2[0], p3[1] - p2[1]];
            let p2p = [p[0] - p2[0], p[1] - p2[1]];
            let temp3 = p2p3[0] * p2p[0] + p2p3[1] * p2p[1];
            let p4p1 = [p1[0] - p4[0], p1[1] - p4[1]];
            let p4p = [p[0] - p4[0], p[1] - p4[1]];
            let temp4 = p4p1[0] * p4p[0] + p4p1[1] * p4p[1];
            if (temp3 * temp4 >= 0) {
                return true;
            }
        }
        return false;
    }

    const pointsTranslationPosition = (array, formerLineWidth, offsetIndex = 0) => {
        let lineWidth = 0.5 * formerLineWidth;
        let ArrayData = [];
        let ArrayIndex = [];
        let newArray = [];
        // let count = newArray.length;
        let index = [];
        let flag = false;
        let t = 0;
        for (let i = 0, length = array.length; i < length - 2; i += 2) {
            if (newArray.length > 5000) {
                ArrayData = ArrayData.concat(newArray);
                newArray = [];
            }
            if (index.length > 5000) {
                ArrayIndex = ArrayIndex.concat(index);
                index = [];
            }
            let [x1, y1, x2, y2] = [array[i], array[i + 1], array[i + 2], array[i + 3]];
            newArray = newArray.concat(translationPosition(x1, y1, x2, y2, lineWidth));
            let temp = newArray.length / 2 + offsetIndex;
            index.push(temp - 4, temp - 3, temp - 2, temp - 3, temp - 2, temp - 1);

            if (i > 0) {
                let length = newArray.length;
                let turningPointLength = 0;
                if (flag) {
                    turningPointLength = 6;
                }
                // length -= turningPointLength;
                let [rb1x, rb1y, rb2x, rb2y] = [newArray[length - 8], newArray[length - 7], newArray[length - 6], newArray[length - 5]];
                let [cax1, cay1, cax2, cay2] = [newArray[length - 4], newArray[length - 3], newArray[length - 2], newArray[length - 1]];
                length -= turningPointLength;
                let [ra1fx, raf1y, raf2x, raf2y] = [newArray[length - 16], newArray[length - 15], newArray[length - 14], newArray[length - 13]];
                let [ra1x, ra1y, ra2x, ra2y] = [newArray[length - 12], newArray[length - 11], newArray[length - 10], newArray[length - 9]];

                if (!pointInPolgon([ra1x, ra1y], [rb1x, rb1y], [rb2x, rb2y], [cax2, cay2], [cax1, cay1])) {
                    newArray.push(ra1x, ra1y);
                } else {
                    newArray.push(ra2x, ra2y);
                }
                newArray.push(x1, y1);
                if (!pointInPolgon([rb1x, rb1y], [ra1fx, raf1y], [raf2x, raf2y], [ra1x, ra1y], [ra2x, ra2y])) {
                    newArray.push(rb1x, rb1y);
                } else {
                    newArray.push(rb2x, rb2y);
                }
                // console.log(newArray.length);
                // t += new Date().getTime() - now;
                let temp = newArray.length / 2 + offsetIndex;
                // console.log(newArray);
                index.push(temp - 3, temp - 2, temp - 1);
                flag = true;
            }

        }

        return {
            ArrayData: ArrayData.concat(newArray),
            ArrayIndex: ArrayIndex.concat(index)
        };
    }

    let data = [];
    /**
   *
   * -0.25, 0.7,
      -0.5, 0,
      0, 0
   * 0.0, 0.5,
      0.0, 0.0,
      0.3, -0.3,
      0.3, -0.5,
      0.5, -0.6,
      0.9, 0.8
   */
    let lineNumber = 3333;
    for (let i = 0; i < lineNumber; i++) {
        let data2 = [];
        for (let j = 0; j < 6; j++) {
            if (Math.random() < 0.5) {
                data2.push((-1) * Math.random());
            } else {
                data2.push(Math.random());
            }
        }
        data.push(data2);
    }


    const drawLines = () => {
        let ArrayData = [];
        let ArrayIndex = [];
        let count = 0;
        let newData = [];
        let index = [];
        for (let i = 0; i < lineNumber; i++) {
            let data2 = data[i];
            let obj = pointsTranslationPosition(data2, 20 / 200, count / 2);
            count += obj.ArrayData.length;
            if (newData.length > 5000) {
                ArrayData = ArrayData.concat(newData);
                newData = [];
            }
            if (index.length > 5000) {
                ArrayIndex = ArrayIndex.concat(index);
                index = [];
            }
            newData = newData.concat(obj.ArrayData);
            index = index.concat(obj.ArrayIndex);

        }
        ArrayData = ArrayData.concat(newData);
        ArrayIndex = ArrayIndex.concat(index);
        newData = [];
        index = [];
        for (let i = 0; i < lineNumber; i++) {
            let data2 = data[i];
            let obj = pointsTranslationPosition(data2, 10 / 200, count / 2);
            count += obj.ArrayData.length;
            if (newData.length > 5000) {
                ArrayData = ArrayData.concat(newData);
                newData = [];
            }
            if (index.length > 5000) {
                ArrayIndex = ArrayIndex.concat(index);
                index = [];
            }
            newData = newData.concat(obj.ArrayData);
            index = index.concat(obj.ArrayIndex);
        }
        ArrayData = ArrayData.concat(newData);
        ArrayIndex = ArrayIndex.concat(index);
        return {
            ArrayData,
            ArrayIndex
        };
    }
    let now = new Date().getTime();
    
    let tempObj = drawLines();

    let vertices = new Float32Array(tempObj.ArrayData);
    let index = tempObj.ArrayIndex;
    let vertexBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
    gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);

    let indexBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
    gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(index), gl.STATIC_DRAW);

    gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);
    gl.enableVertexAttribArray(a_Position);

    gl.clearColor(0.0, 0.0, 0.0, 1.0);
    gl.clear(gl.COLOR_BUFFER_BIT);
    gl.uniform4f(u_FragColor, ...[0.0, 1.0, 0.0, 1.0]);
    gl.drawElements(gl.TRIANGLES, index.length / 2, gl.UNSIGNED_SHORT, 0);
    gl.uniform4f(u_FragColor, ...[1.0, 0.0, 0.0, 1.0]);
    gl.drawElements(gl.TRIANGLES, index.length / 2, gl.UNSIGNED_SHORT, index.length);
    // console.log(new Date().getTime() - now);
    alert(new Date().getTime() - now);

};